package cn.wolfcode.business.service.impl;

import cn.wolfcode.business.domain.BusStatement;
import cn.wolfcode.business.mapper.BusStatementMapper;
import cn.wolfcode.business.service.IBusStatementService;
import cn.wolfcode.business.util.DateUtil;
import cn.wolfcode.business.util.RegexUtils;
import cn.wolfcode.business.util.VehiclePlateNoUtil;
import cn.wolfcode.common.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 结算单Service业务层处理
 * 
 * @author wolfcode
 * @date 2025-09-22
 */
@Service
public class BusStatementServiceImpl implements IBusStatementService 
{
    @Autowired
    private BusStatementMapper busStatementMapper;

    /**
     * 查询结算单
     * 
     * @param id 结算单主键
     * @return 结算单
     */
    @Override
    public BusStatement selectBusStatementById(Long id)
    {
        return busStatementMapper.selectBusStatementById(id);
    }

    /**
     * 查询结算单列表
     * 
     * @param busStatement 结算单
     * @return 结算单
     */
    @Override
    public List<BusStatement> selectBusStatementList(BusStatement busStatement) throws ParseException {
        // 对高级搜索的时间进行处理。
        // 接收到结束时间
        String endActualArrivalTime = (String) busStatement.getParams().get("endActualArrivalTime");
        // 将结束时间转换为指定格式的 Date 类型
        Date date = DateUtil.parseDate(endActualArrivalTime, "yyyy-MM-dd");
        // 将结束时间 +1天 -1秒
        Date addDay = DateUtil.changeDate(date, Calendar.DAY_OF_YEAR, 1);
        Date subSecond = DateUtil.changeDate(addDay, Calendar.SECOND, -1);
        // 将日期类型在转换回字符串类型
        String endTime = DateUtil.Date2String(subSecond, "yyyy-MM-dd HH:mm:ss");
        // 将转换后的时间设置到结束时间中。
        busStatement.getParams().put("endActualArrivalTime",endTime);
        // 传入 is_delete 字段
        busStatement.setIsDelete(BusStatement.IS_NOT_DELETE);
        return busStatementMapper.selectBusStatementList(busStatement);
    }

    /**
     * 新增结算单
     * 
     * @param busStatement 结算单
     * @return 结果
     */
    @Override
    public int insertBusStatement(BusStatement busStatement)
    {
        //  1. 首先前台所有的验证后端都要在做一次。也称之为参数合理化验证。也就是前台的6个非空数据我们都要验证。
        if(busStatement == null){
            throw new RuntimeException("非法参数");
        }
        if(busStatement.getCustomerName() == null || busStatement.getCustomerPhone() == null
                || busStatement.getActualArrivalTime() == null || busStatement.getLicensePlate() == null
                || busStatement.getCarSeries() == null || busStatement.getServiceType() == null){
            throw new RuntimeException("非法参数");
        }
        // 	2. 联系方式合理化验证。
        if (!RegexUtils.isPhoneLegal(busStatement.getCustomerPhone())) {
            throw new RuntimeException("手机号码格式有误");
        }
        // 	3. 车牌号码合理化验证。
        if (VehiclePlateNoUtil.getVehiclePlateNo(busStatement.getLicensePlate()) == null) {
            throw new RuntimeException("车牌号码格式有误");
        }
        // 	4. 到店时间需要早于当前系统时间
        Date nowDate = new Date();
        if(!busStatement.getActualArrivalTime().before(nowDate)){
            throw new RuntimeException("到店时间异常");
        }
        // 5. 安全性验证  -->  默认新增的数据状态为消费中
        busStatement.setStatus(BusStatement.STATUS_CONSUME);
        // 6. 安全性验证 -->  设置 IS_NOT_DELETE 保证新增的是有效用户
        busStatement.setIsDelete(BusStatement.IS_NOT_DELETE);
        busStatement.setCreateTime(DateUtils.getNowDate());
        return busStatementMapper.insertBusStatement(busStatement);
    }

    /**
     * 修改结算单
     * 
     * @param busStatement 结算单
     * @return 结果
     */
    @Override
    public int updateBusStatement(BusStatement busStatement)
    {
        //  1. 首先前台所有的验证后端都要在做一次。也称之为参数合理化验证。也就是前台的6个非空数据我们都要验证。
        if(busStatement == null){
            throw new RuntimeException("非法参数");
        }
        if(busStatement.getCustomerName() == null || busStatement.getCustomerPhone() == null
                || busStatement.getActualArrivalTime() == null || busStatement.getLicensePlate() == null
                || busStatement.getCarSeries() == null || busStatement.getServiceType() == null){
            throw new RuntimeException("非法参数");
        }
        // 	2. 联系方式合理化验证。
        if (!RegexUtils.isPhoneLegal(busStatement.getCustomerPhone())) {
            throw new RuntimeException("手机号码格式有误");
        }
        // 	3. 车牌号码合理化验证。
        if (VehiclePlateNoUtil.getVehiclePlateNo(busStatement.getLicensePlate()) == null) {
            throw new RuntimeException("车牌号码格式有误");
        }
        // 	4. 到店时间需要早于当前系统时间
        Date nowDate = new Date();
        if(!busStatement.getActualArrivalTime().before(nowDate)){
            throw new RuntimeException("到店时间异常");
        }
        // 5. 只有状态是消费中的结算单才可以进行编辑操作。
        BusStatement oldObj = this.selectBusStatementById(busStatement.getId());
        if(oldObj == null || oldObj.getStatus() == null || oldObj.getIsDelete() == null){
            throw new RuntimeException("非法参数");
        }
        if(BusStatement.STATUS_PAID.equals(oldObj.getStatus()) ||
            (!oldObj.getStatus().equals(busStatement.getStatus()))){
            throw new RuntimeException("只有消费中的结算单才可以进行编辑操作");
        }
        // 6. 验证 IS_DELETE 字段 = 0  才是有效用户，才可以进行编辑擦做。
        if(BusStatement.IS_DELETE.equals(oldObj.getIsDelete()) ||
                (!oldObj.getIsDelete().equals(busStatement.getIsDelete()))){
            throw new RuntimeException("只有有效的结算单才可以进行编辑操作");
        }
        busStatement.setCreateTime(DateUtils.getNowDate());
        return busStatementMapper.updateBusStatement(busStatement);
    }

    /**
     * 批量删除结算单
     * 
     * @param ids 需要删除的结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementByIds(Long[] ids)
    {
        return busStatementMapper.deleteBusStatementByIds(ids);
    }

    /**
     * 软删除结算单信息（将is_delete 字段修改为1）
     * 
     * @param id 结算单主键
     * @return 结果
     */
    @Override
    public int deleteBusStatementById(Long id)
    {
        // 参数合法性验证
        if (id == null) {
            throw new RuntimeException("非法参数");
        }
        BusStatement statement = this.selectBusStatementById(id);
        if(statement == null || statement.getStatus() == null){
            throw new RuntimeException("非法操作");
        }
        // 删除状态必须是 IS_DELETE = 0 才可以进行删除操作。
        if(BusStatement.IS_DELETE.equals(statement.getIsDelete())){
            throw new RuntimeException("已经删除的结算单请勿重复删除");
        }
        // 判断状态必须是消费中的才能进行删除操作
        if(BusStatement.STATUS_PAID.equals(statement.getStatus())){
            throw new RuntimeException("只有状态为消费中的结算单才可以进行删除操作");
        }
        return busStatementMapper.updateIsDelete(id,BusStatement.IS_DELETE);
    }

    /**
     * 根据结算单 id 更新 总金额、总数量、折扣价
     * @param statementId 结算单 id
     * @param totalAmount 总金额
     * @param totalQuantity 总数量
     * @param discountAmount 折扣价
     */
    @Override
    public void updateAmount(Long statementId, BigDecimal totalAmount, BigDecimal totalQuantity, BigDecimal discountAmount) {
        busStatementMapper.updateAmount(statementId,totalAmount,totalQuantity,discountAmount);
    }

    /**
     * 根据结算单 id 更新 收款人、收款时间、支付状态
     * @param statementId 结算单 id
     * @param payId 收款人 id
     * @param date  收款时间
     * @param statusPaid  状态
     */
    @Override
    public int updatePayStatus(Long statementId, Long payId, Date date, Integer statusPaid) {
       return busStatementMapper.updatePayStatus(statementId, payId,date,statusPaid);
    }
}
